This example is for the UNIQUE constraint and the PRIMARY KEY constraint. The table in SQL can be created by $(D $(D sql CREATE TABLE Brands ( Id INTEGER NOT NULL PRIMARY KEY, BrandName TEXT UNIQUE ); ))
Any column marked with @PrimaryKeyColumn must also have @NotNull. Unlike SQLite, if a column is marked as int and @PrimaryKeyColumn it is not auto-incremented.
1 import db_constraints; 2 3 class Brand 4 { 5 private int _Id; 6 // marking Id with not null and primary key 7 @NotNull @PrimaryKeyColumn 8 @property int Id() 9 { 10 return _Id; 11 } 12 @property void Id(int value) 13 { 14 setter(_Id, value); 15 } 16 17 private string _BrandName; 18 // marking BrandName with UniqueConstraintColumn 19 // so the collection will know this property should be 20 // unique for all records 21 @UniqueConstraintColumn!("Unique") 22 @property string BrandName() 23 { 24 return _BrandName; 25 } 26 @property void BrandName(string value) 27 { 28 setter(_BrandName, value); 29 } 30 31 this(int Id_, string BrandName_) 32 { 33 this._Id = Id_; 34 this._BrandName = BrandName_; 35 // do not forget to initialize the keyed item! 36 initializeKeyedItem(); 37 } 38 39 // do not forget to add in the keyed item! 40 mixin KeyedItem!(); 41 } 42 43 // this is what I call the plural class 44 // or table class. This is the collection 45 // of rows (in this example Brands). 46 class Brands 47 { 48 // this mixin already does the 49 // initializations and every method 50 // I want for this tutorial so I 51 // do not need anything else. 52 mixin KeyedCollection!(Brand); 53 } 54 55 import std.exception : assertNotThrown, assertThrown; 56 57 // UNIQUE constraint 58 { 59 // we can start by putting two records into the collection. 60 // now brands holds a record for Coca Cola and Pepsi 61 auto brands = new Brands([new Brand(1, "Coca Cola"), 62 new Brand(2, "Pepsi")]); 63 64 auto anotherPepsi = new Brand(3, "Pepsi"); 65 // if we try to add another record that has Pepsi for 66 // the brand name we will get a unique constraint exception 67 assertThrown!UniqueConstraintException(brands.add(anotherPepsi)); 68 69 // we can see if the new record will violate any unique constraints 70 // before we add it to the collection by using violatesUniqueConstraints 71 assert(brands.violatesUniqueConstraints(anotherPepsi)); 72 } 73 74 // PRIMARY KEY constraint 75 { 76 // the primary key is unique and not null 77 // by default we can use the primary key to look up 78 // records in the collection 79 auto brands = new Brands([new Brand(1, "Coca Cola"), 80 new Brand(2, "Pepsi")]); 81 82 // since Pepsi's Id is the primary key we can use 2 to find pepsi 83 assert(brands[2].BrandName == "Pepsi"); 84 assert(brands[2].Id == 2); 85 // this is because brands is really an associative array that uses the 86 // primary key in this case as the AA key. We can check if the 87 // collection already contains a primary key of 2 by using contains 88 assert(brands.contains(2)); 89 // and does not contain 4 90 assert(!brands.contains(4)); 91 // if you try to get an item that is not there you will get an exception 92 assertThrown!KeyedException(brands[4].BrandName); 93 94 // lets add two more records 95 brands ~= [new Brand(3, "Sun"), new Brand(4, "Oracle")]; 96 97 // now it does contain 4 98 assert(brands.contains(4)); 99 assertNotThrown!KeyedException(brands[4].BrandName); 100 }